Deploying Dockerized Applications
This section covers how to deploy Dockerized applications using various methods. We'll cover:
- Using Docker Compose to Manage Multi-Container Applications
- Deployment Using Pre-built Docker Hub Images
- Building and Running an Image from a Dockerfile
- Deploying Flask with MySQL, Gunicorn, and Nginx (Detailed production-level deployment)
1. Using Docker Compose to Manage Multi-Container Applications
Scenario: You want to deploy a multi-container application using Docker Compose. In this case, we’ll start with a simple example of deploying an Nginx web server.
Directory Structure:
simple-nginx/
└── docker-compose.yml
docker-compose.yml:
version: '3'
services:
web:
image: nginx:alpine # Pull a lightweight Nginx image from Docker Hub
ports:
- "8080:80" # Map port 8080 on the host to port 80 in the container
Step-by-Step Explanation:
image: nginx:alpine
: We’re using the lightweightnginx:alpine
image from Docker Hub.ports: "8080:80"
: This maps port8080
on your local machine to port80
inside the container (which is where Nginx serves its content). This allows you to access the Nginx web server throughhttp://localhost:8080
.
How to Deploy:
- Create a directory called
simple-nginx
. - Inside the directory, create a file called
docker-compose.yml
with the content above. - Run the following command in the same directory:
docker compose up
- Open your browser and go to
http://localhost:8080
. You should see the default Nginx welcome page.
2. Deploying Flask Application with MySQL
Scenario: Deploying a simple Flask application that connects to a MySQL database using Docker Compose.
Directory Structure:
flask-mysql-app/
├── docker-compose.yml
└── flask-app/
├── Dockerfile
├── app.py
├── requirements.txt
docker-compose.yml:
version: '3'
services:
web:
build: ./flask-app # Build the Flask app from the Dockerfile in the "flask-app" directory
ports:
- "5000:5000" # Map port 5000 on the host to port 5000 inside the container
environment:
- FLASK_ENV=development
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: flask_db
MYSQL_USER: user
MYSQL_PASSWORD: userpassword
ports:
- "3306:3306"
Dockerfile:
# Use the official Python image
FROM python:3.8-slim
# Set the working directory
WORKDIR /app
# Copy current directory contents into /app
COPY . /app
# Install required Python packages
RUN pip install -r requirements.txt
# Command to run the Flask app
CMD ["python", "app.py"]
app.py:
from flask import Flask
import mysql.connector
app = Flask(__name__)
@app.route('/')
def hello():
# Connect to the MySQL database
db = mysql.connector.connect(
host="db", # This matches the MySQL service name in docker-compose
user="user",
password="userpassword",
database="flask_db"
)
return "Connected to MySQL Database!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
requirements.txt:
Flask
mysql-connector-python
Step-by-Step Explanation:
build: ./flask-app
: We’re building a custom Flask application defined in theDockerfile
located in theflask-app
directory.depends_on: db
: Ensures that thedb
service (MySQL) starts before the Flask app.- MySQL Configuration: The
db
service is running a MySQL 5.7 container, with environment variables to configure the root password, database, and user credentials. - Networking: Flask connects to the MySQL service using the hostname
db
, which is automatically set up by Docker Compose.
How to Deploy:
- Create the directory structure as shown above.
- Place the
docker-compose.yml
,Dockerfile
,app.py
, andrequirements.txt
in their respective locations. - Run:
docker compose up --build
- Visit
http://localhost:5000
to see your Flask app, which connects to the MySQL database.
3. Deploying Using Pre-built Docker Hub Images
Scenario: You want to quickly deploy a Redis server by pulling the official image from Docker Hub.
Directory Structure:
redis-server/
└── docker-compose.yml
docker-compose.yml:
version: '3'
services:
redis:
image: redis:latest # Pull the official Redis image from Docker Hub
ports:
- "6379:6379" # Map port 6379 on the host to port 6379 in the container
Step-by-Step Explanation:
image: redis:latest
: This pulls the latest Redis image from Docker Hub.ports: "6379:6379"
: This maps port6379
on your host machine to port6379
inside the container, which is the default Redis port.
How to Deploy:
- Create a directory called
redis-server
. - Inside that directory, create a file called
docker-compose.yml
with the content above. - Run:
docker compose up
- Redis will now be running, and you can interact with it at
localhost:6379
.
4. Advanced Scenario: Deploying Flask with MySQL, Gunicorn, and Nginx
Scenario: You want to deploy a production-ready Flask application that uses MySQL as the database, Gunicorn as the WSGI server, and Nginx as the reverse proxy.
Directory Structure:
flask-gunicorn-nginx/
├── docker-compose.yml
├── flask-app/
│ ├── Dockerfile
│ ├── app.py
│ ├── requirements.txt
└── nginx/
└── nginx.conf
docker-compose.yml:
version: '3'
services:
web:
build: ./flask-app
command: gunicorn -w 4 -b 0.0.0.0:5000 app:app
expose:
- "5000"
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: flask_db
MYSQL_USER: user
MYSQL_PASSWORD: userpassword
ports:
- "3306:3306"
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web
Dockerfile (Flask App):
# Use the official Python image
FROM python:3.8-slim
# Set the working directory
WORKDIR /app
# Copy current directory contents into /app
COPY . /app
# Install required Python packages
RUN pip install -r requirements.txt
# Command to run the Flask app via Gunicorn
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
app.py:
from flask import Flask
import mysql.connector
app = Flask(__name__)
@app.route('/')
def hello():
# Connect to the MySQL database
db = mysql.connector.connect(
host="db",
user="user",
password="userpassword",
database="flask_db"
)
return "Hello, world! This is a production-ready Flask app with MySQL and Gunicorn."
if __name__ == "__main__":
app.run(host='0.0.0.0')
requirements.txt:
Flask
gunicorn
mysql-connector-python
nginx.conf:
server {
listen 80;
location / {
proxy_pass http://web:5000; # Proxy to the Gunicorn Flask app
}
}
Step-by-Step Explanation:
- Web service: Flask app is served using Gunicorn, which is a production-level WSGI server.
- Nginx: Acts as a reverse proxy, forwarding HTTP requests to the Flask app running on Gunicorn.
- MySQL: A relational database service to store data, used by the Flask app.
- Command
gunicorn -w 4 -b 0.0.0.0:5000 app:app
: Starts the Gunicorn server with 4 worker processes, listening on port5000
.
How to Deploy:
- Set up the directory structure and add the files as shown.
- Run the following command to start the application:
docker compose up --build
- Visit
http://localhost
to see the Flask app served via Nginx.